﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;

namespace YArchitech.Revit
{
	public class YJKRotateFamilyInstance
	{
		public YJKRotateFamilyInstance()
		{
		}

		public YJKRotateFamilyInstance(IList<Element> IlistElem)
		{
			this.listElement = IlistElem;
		}

		private Element GetRotateFI()
		{
			Element result = null;
			foreach (Element element in this.listElement)
			{
				if (element is FamilyInstance)
				{
					result = element;
				}
				this.icElementId.Add(element.Id);
			}
			return result;
		}

		private Line GeElemettAxis(Autodesk.Revit.DB.Document doc, Element elem)
		{
			Line result = null;
			if (elem is FamilyInstance)
			{
				XYZ point = (elem.Location as LocationPoint).Point;
				result = doc.CreatYJKLine(point, new XYZ(0.0, 0.0, 1.0), false);
			}
			return result;
		}

		public string RotateElem(Autodesk.Revit.DB.Document doc, double degree)
		{
			string result = "";
			Element rotateFI = this.GetRotateFI();
			if (rotateFI == null)
			{
				return "选择的旋转实体集合，\n其中必须包含一个族实例，\n且仅可有一个族实例！";
			}
			Line line = this.GeElemettAxis(doc, rotateFI);
			double num = degree / 180.0 * Math.PI;
			ElementTransformUtils.RotateElements(doc, this.icElementId, line, num);
			return result;
		}

		public string RotateElem(Autodesk.Revit.DB.Document doc, FamilyInstance fi, double degree)
		{
			string result = "";
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			Line line = this.GeElemettAxis(doc, fi);
			double num = degree / 180.0 * Math.PI;
			this.icElementId = new List<ElementId>();
			this.icElementId.Add(fi.Id);
			ElementTransformUtils.RotateElements(doc, this.icElementId, line, num);
			return result;
		}

		public string RotateElem(FamilyInstance fi, XYZ basePnt, XYZ vector, double degree)
		{
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			Document document = fi.Document;
			Line line = document.CreatYJKLine(basePnt, vector, false);
			double num = degree / 180.0 * Math.PI;
			this.icElementId = new List<ElementId>();
			this.icElementId.Add(fi.Id);
			ElementTransformUtils.RotateElements(document, this.icElementId, line, num);
			return "";
		}

		public string RotatesElem(FamilyInstance fi, XYZ basePnt, XYZ vector, double degree)
		{
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			Document document = fi.Document;
			Line line = document.CreatYJKLine(basePnt, vector, false);
			ElementTransformUtils.RotateElement(document, fi.Id, line, degree);
			return "";
		}

		public string MoveElem(FamilyInstance fi, XYZ moveToPoint)
		{
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			Document document = fi.Document;
			XYZ point = (fi.Location as LocationPoint).Point;
			XYZ xyz = moveToPoint.Subtract(point);
			ElementTransformUtils.MoveElement(document, fi.Id, xyz);
			return "";
		}

		public string MoveElem(XYZ moveVector, FamilyInstance fi)
		{
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			ElementTransformUtils.MoveElement(fi.Document, fi.Id, moveVector);
			return "";
		}

		public string MoveFamilyInstance(FamilyInstance fi, XYZ moveToPoint)
		{
			if (fi == null)
			{
				return "族实例不能为空！";
			}
			Document document = fi.Document;
			ElementTransformUtils.MoveElement(document, fi.Id, moveToPoint);
			ElementTransformUtils.MoveElement(document, fi.Id, -1.0 * moveToPoint);
			return "";
		}

		public void MovePiping(Pipe pipe)
		{
			Document document = pipe.Document;
			XYZ basisX = new YJKPiping<Pipe>(pipe).EndConnector.Connector.CoordinateSystem.BasisX;
			ElementTransformUtils.MoveElement(document, pipe.Id, 0.001 * basisX);
			ElementTransformUtils.MoveElement(document, pipe.Id, -0.001 * basisX);
		}

		public void MovePiping(Pipe pipe, XYZ baseVector)
		{
			Document document = pipe.Document;
			new YJKPiping<Pipe>(pipe);
			ElementTransformUtils.MoveElement(document, pipe.Id, 0.001 * baseVector);
			ElementTransformUtils.MoveElement(document, pipe.Id, -0.001 * baseVector);
		}

		public void MovePiping(Duct duct)
		{
			Document document = duct.Document;
			XYZ basisX = new YJKPiping<Duct>(duct).EndConnector.Connector.CoordinateSystem.BasisX;
			ElementTransformUtils.MoveElement(document, duct.Id, 0.001 * basisX);
			ElementTransformUtils.MoveElement(document, duct.Id, -0.001 * basisX);
			document.Regenerate();
		}

		public void MovePiping(Element elem, XYZ vector)
		{
			Document document = elem.Document;
			ElementTransformUtils.MoveElement(document, elem.Id, 0.001 * vector);
			ElementTransformUtils.MoveElement(document, elem.Id, -0.001 * vector);
			document.Regenerate();
		}

		public void MoveElements(XYZ moveVector, IList<Element> listElem)
		{
			Document document = listElem[0].Document;
			List<ElementId> list = new List<ElementId>();
			foreach (Element element in listElem)
			{
				list.Add(element.Id);
			}
			ElementTransformUtils.MoveElements(document, list, moveVector);
		}

		public void MoveElement(XYZ moveVector, Element elem)
		{
			ElementTransformUtils.MoveElements(elem.Document, new List<ElementId>
			{
				elem.Id
			}, moveVector);
		}

		public void MoveTextNote(TextNote text, XYZ vector)
		{
			if (text != null)
			{
				Document document = text.Document;
				ElementTransformUtils.MoveElement(document, text.Id, vector);
				ElementTransformUtils.MoveElement(document, text.Id, -vector);
			}
		}

		public void MirrorFamilyInstance(FamilyInstance fi, XYZ xVec, XYZ yVec, XYZ mirrorPnt)
		{
			Document document = fi.Document;
			Plane plane = new Plane(xVec, yVec, mirrorPnt);
			ElementTransformUtils.MirrorElement(document, fi.Id, plane);
		}

		private IList<Element> listElement;

		private ICollection<ElementId> icElementId = new List<ElementId>();
	}
}
